package nc.tb.cube.relation;

import java.util.ArrayList;
import java.util.HashMap;

import nc.tb.app.CommonPlan;
import nc.tb.ctl.StyleSheetCTL;
import nc.tb.cube.model.MetaPlan;
import nc.tb.cube.vo.CdFlowDefVO;
import nc.tb.pub.services.NtbSuperServiceGetter;
import nc.vo.pub.BusinessException;

public class CubeRelationCtl {

	public static CubeRelationDef createCubeRelationDef(String name) {
		CdFlowDefVO vo = new CdFlowDefVO();
		vo.setPk_cube(CubeRelation.pk_cube_def);
		vo.setAfterstatus(CubeRelation.afterstatus_def);
		vo.setAction(CubeRelation.action_cubeRelationDef);
		vo.setMatchindex(0);
		vo.setFilterexpress(name);
		return new CubeRelationDef(vo);
	}
	
	public static CubeRelationMember createCubeRelationMember(CubeRelationDef def) {
		CdFlowDefVO vo = new CdFlowDefVO();
		vo.setPk_cube(def.getPrimaryKey());
		vo.setAfterstatus(CubeRelation.afterstatus_member);
		vo.setAction(CubeRelation.action_cubeRelation_Calculate);
		return new CubeRelationMember(vo, def);
	}
	
	public static HashMap<CubeRelationDef, ArrayList<CubeRelationMember>> getAllCubeRelations() throws BusinessException {
		HashMap<CubeRelationDef, ArrayList<CubeRelationMember>> hm = new HashMap<CubeRelationDef, ArrayList<CubeRelationMember>>();
		CdFlowDefVO[] vos = (CdFlowDefVO[])NtbSuperServiceGetter.getINtbSuper().queryByCondition(CdFlowDefVO.class, " afterstatus="+CubeRelation.afterstatus_def+" or afterstatus="+CubeRelation.afterstatus_member+" order by afterstatus");
//		HashMap<String,CubeRelationDef> hmPk2Def = new HashMap<String, CubeRelationDef>();
		if (vos != null) {
			setValue2MapByVo(hm, vos);
//			for (int i=0; i<vos.length; i++) {
//				if (vos[i].getAfterstatus() == CubeRelation.afterstatus_def) {
//					CubeRelationDef def = new CubeRelationDef(vos[i]);
//					hm.put(def, new ArrayList<CubeRelationMember>());
//					hmPk2Def.put(def.getPrimaryKey(), def);
//				}
//				else {
//					CubeRelationDef def = hmPk2Def.get(vos[i].getPk_cube());
//					if (def != null) {
//						ArrayList<CubeRelationMember> al = hm.get(def);
//						if (al == null) {
//							al = new ArrayList<CubeRelationMember>();
//							hm.put(def, al);
//						}
//						al.add(new CubeRelationMember(vos[i], def));
//					}
//				}
//			}
		}
		return hm;
	}
	
	private static void setValue2MapByVo(HashMap<CubeRelationDef, ArrayList<CubeRelationMember>> hm, CdFlowDefVO[] vos) {
		if (vos != null) {
			HashMap<String,CubeRelationDef> hmPk2Def = new HashMap<String, CubeRelationDef>();
			for (int i=0; i<vos.length; i++) {
				if (vos[i].getAfterstatus() == CubeRelation.afterstatus_def) {
					CubeRelationDef def = new CubeRelationDef(vos[i]);
					hm.put(def, new ArrayList<CubeRelationMember>());
					hmPk2Def.put(def.getPrimaryKey(), def);
				}
				else {
					CubeRelationDef def = hmPk2Def.get(vos[i].getPk_cube());
					if (def != null) {
						ArrayList<CubeRelationMember> al = hm.get(def);
						if (al == null) {
							al = new ArrayList<CubeRelationMember>();
							hm.put(def, al);
						}
						al.add(new CubeRelationMember(vos[i], def));
					}
				}
			}
		}
	}
	
	public static void save(CubeRelationDef def, ArrayList<CubeRelationMember> member, boolean isDefChanged) throws BusinessException {
		boolean isDefNew = def.getPrimaryKey() == null;
		if (isDefChanged) {
			CdFlowDefVO vo = def.getVO();
			if (vo.getPrimaryKey() == null) {
				vo.setPrimaryKey(NtbSuperServiceGetter.getINtbSuper().insert(vo));
			}
			else {
				NtbSuperServiceGetter.getINtbSuper().update(vo);
			}
		}
		if (member != null && !member.isEmpty()) {
			String pk_def = def.getPrimaryKey();
			if (!isDefNew) {
				NtbSuperServiceGetter.getINtbSuper().deleteByWhereClause(CdFlowDefVO.class, "afterstatus="+CubeRelation.afterstatus_member+" and pk_cube='"+pk_def+"'");
			}
			ArrayList<CdFlowDefVO> vos = new ArrayList<CdFlowDefVO>();
			for (CubeRelationMember mem : member) {
				mem.setPrimaryKey(null);
				mem.setPk_parent(pk_def);
				vos.add(mem.getVO());
			}
			String[] pks = NtbSuperServiceGetter.getINtbSuper().insertArray(vos.toArray(new CdFlowDefVO[0]));
			for (int i=0; i<pks.length; i++) {
				member.get(i).setPrimaryKey(pks[i]);
			}
		}
	}
	
	public static ArrayList<CubeRelation[]> getCubeRelationsByPlan(CommonPlan[] plans, HashMap<CubeRelationDef, ArrayList<CubeRelationMember>> hm) throws BusinessException {
		ArrayList<CubeRelation[]> rtn = new ArrayList<CubeRelation[]>();
		HashMap<String,String> hmCubePk2Code = new HashMap<String, String>();
		if (plans != null) {
			for (int i=0; i<plans.length; i++) {
				String pk_cube = plans[i].getPlanInfo().getPk_stl_sht();
				if (hmCubePk2Code.containsKey(pk_cube))
					continue;
				MetaPlan cube = StyleSheetCTL.getCubeByPK(pk_cube);
				if (cube != null)
					hmCubePk2Code.put(pk_cube, cube.getObjcode()+",");
			}
			StringBuffer where = new StringBuffer();
			where.append(" afterstatus=").append(CubeRelation.afterstatus_member);
//			where.append(" and action='").append(CubeRelation.action_cubeRelation_Calculate).append("'");
			for (String code : hmCubePk2Code.values()) {
				where.append(" and beforestatus like '%").append(code).append("%'");
			}
			CdFlowDefVO[] vos = (CdFlowDefVO[])NtbSuperServiceGetter.getINtbSuper().queryByCondition(CdFlowDefVO.class, where.toString());
			if (vos != null && vos.length > 0) {
				HashMap<String,CdFlowDefVO> hmDefPk2Vo = new HashMap<String, CdFlowDefVO>();
				HashMap<String,CdFlowDefVO> hmMember2Vo = new HashMap<String, CdFlowDefVO>();
				for (int i=0; i<vos.length; i++) {
					hmDefPk2Vo.put(vos[i].getPk_cube(), null);
					hmMember2Vo.put(vos[i].getPrimaryKey(), vos[i]);
				}
				where.setLength(0);
				for (String pk : hmDefPk2Vo.keySet()) {
					if (where.length() > 0)
						where.append(",");
					where.append("'").append(pk).append("'");
				}
				String pks = where.toString();
				where.setLength(0);
				where.append(" afterstatus=").append(CubeRelation.afterstatus_def).append(" and pk_obj in (").append(pks)
					.append(") or afterstatus=").append(CubeRelation.afterstatus_member).append(" and pk_cube in (").append(pks)
					.append(") order by afterstatus");
				vos = (CdFlowDefVO[])NtbSuperServiceGetter.getINtbSuper().queryByCondition(CdFlowDefVO.class, where.toString());
				setValue2MapByVo(hm, vos);
				
				for (CubeRelationDef def : hm.keySet()) {
					ArrayList<CubeRelationMember> members = hm.get(def);
					if (members != null) {
						for (CubeRelationMember mem : members) {
							if (hmMember2Vo.containsKey(mem.getPrimaryKey())) {
								CubeRelation[] match = new CubeRelation[2];
								match[0] = def;
								match[1] = mem;
								rtn.add(match);
							}
						}
					}
				}
			}
		}
		return rtn;
	}
}
